// Package dao
// Created by GoLand
// @User: lenora
// @Date: 2023/11/29
// @Time: 18:32

package dao

import (
	"context"
	"database/sql"
	"github.com/go-sql-driver/mysql"
	"gorm.io/gorm"
	"time"
)

type UserDAO interface {
	FindById(ctx context.Context, uid uint64) (User, error)
	FindByName(ctx context.Context, name string) (User, error)
	FindByPhone(ctx context.Context, phone string) (User, error)
	Insert(ctx context.Context, u User) error
	UpdateById(ctx context.Context, u User) error
	FindByOpenid(ctx context.Context, openid string) (User, error)
}

type GormUserDAO struct {
	db *gorm.DB
}

func NewUserDAO(db *gorm.DB) UserDAO {
	return &GormUserDAO{db: db}
}

func (dao *GormUserDAO) Insert(ctx context.Context, u User) error {
	now := time.Now().UnixMilli()
	u.Ctime = now
	u.Utime = now
	err := dao.db.WithContext(ctx).Create(&u).Error
	if e, ok := err.(*mysql.MySQLError); ok {
		if e.Number == DuplicateError {
			//用户重复
			return ErrDuplicateUser
		}
	}
	return err
}

func (dao *GormUserDAO) FindByName(ctx context.Context, name string) (User, error) {
	var u User
	err := dao.db.WithContext(ctx).Where("user_name = ?", name).First(&u).Error
	return u, err
}

func (dao *GormUserDAO) FindById(ctx context.Context, uid uint64) (User, error) {
	var u User
	err := dao.db.WithContext(ctx).Where("id = ?", uid).First(&u).Error
	return u, err
}

func (dao *GormUserDAO) UpdateById(ctx context.Context, u User) error {
	u.Utime = time.Now().UnixMilli()
	err := dao.db.WithContext(ctx).Where("id = ?", u.Id).Updates(&u).Error
	return err
}

func (dao *GormUserDAO) FindByPhone(ctx context.Context, phone string) (User, error) {
	var u User
	err := dao.db.WithContext(ctx).Where("phone = ?", phone).First(&u).Error
	return u, err
}

func (dao *GormUserDAO) FindByOpenid(ctx context.Context, openid string) (User, error) {
	var u User
	err := dao.db.WithContext(ctx).Where("openid = ?", openid).First(&u).Error
	return u, err
}

type User struct {
	//数据表结构
	Id       uint64         `gorm:"autoIncrement:true;primaryKey;column:id;type:int(11) unsigned;not null"`
	UserName sql.NullString `gorm:"unique;column:user_name;type:varchar(50)"` //NullString 代表值可以为null
	Password string         `gorm:"column:password;not null"`
	Phone    sql.NullString `gorm:"column:phone;type:varchar(15);unique"`
	Nickname string         `gorm:"column:nickname;type:varchar(50);not null"`
	Birth    string         `gorm:"column:birth;type:char(12);not null"`
	Desc     string         `gorm:"column:desc;type:text"`
	Openid   sql.NullString `gorm:"column:openid"`
	Ctime    int64
	Utime    int64
}
